package com.huawei.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 读取 SQL 文件并执行到 MySQL 数据库
 */
public class SqlFileExecutor {

    // 在 Java JDBC 中，executeBatch() 支持 DELETE、INSERT、UPDATE 等 DML 语句，但 不支持 TRUNCATE、CREATE、DROP 等 DDL 语句（或行为不可靠）
    /**
     * 高性能批量插入 SQL 执行器（仅支持同结构 INSERT）
     * 使用 PreparedStatement + addBatch() + executeBatch()
     */
    // 每批次提交的记录数（建议 500~2000）
    private static final int BATCH_SIZE = 1000;

    public static void executeBatchInsert(Connection conn, String sqlFilePath)
            throws IOException, SQLException {

        // ✅ 关键：按分号分割完整 SQL 语句（支持跨行）
        List<String> sqlStatements = readSqlStatements(sqlFilePath);
        if (sqlStatements.isEmpty()) {
            System.out.println("SQL 文件为空");
            return;
        }

        // 从第一条 SQL 提取模板
        String firstSql = sqlStatements.get(0);
        SqlTemplate template = parseInsertSql(firstSql);

        System.out.println("检测到 INSERT 模板: " + template.getSqlTemplate());
        System.out.println("参数数量: " + template.getParamCount());
        System.out.println("共 " + sqlStatements.size() + " 条记录");

        conn.setAutoCommit(false);
        try (PreparedStatement ps = conn.prepareStatement(template.getSqlTemplate())) {
            int totalProcessed = 0;

            for (String sql : sqlStatements) {
                Object[] params = extractParams(sql);
                if (params.length != template.getParamCount()) {
                    throw new IllegalArgumentException("SQL 参数数量不匹配: " + sql);
                }

                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
                ps.addBatch();
                totalProcessed++;

                if (totalProcessed % BATCH_SIZE == 0) {
                    ps.executeBatch();
                    conn.commit();
                    ps.clearBatch();
                    System.out.println("✅ 已提交 " + totalProcessed + " 条记录");
                }
            }

            if (totalProcessed % BATCH_SIZE != 0) {
                ps.executeBatch();
                conn.commit();
                System.out.println("✅ 最终提交 " + (totalProcessed % BATCH_SIZE) + " 条记录");
            }
        } finally {
            conn.setAutoCommit(true);
        }

        System.out.println("🎉 批量插入完成，共 " + sqlStatements.size() + " 条记录");
    }

    /**
     * ✅ 读取 SQL 文件，按分号分割成完整语句（支持跨行）
     */
    private static List<String> readSqlStatements(String filePath) throws IOException {
        StringBuilder fullContent = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                // 跳过注释行
                if (line.trim().startsWith("--") || line.trim().startsWith("#")) {
                    continue;
                }
                fullContent.append(line).append("\n");
            }
        }

        List<String> statements = new ArrayList<>();
        String content = fullContent.toString().trim();
        if (content.isEmpty()) return statements;

        // 按分号分割，但保留分号前的内容
        String[] parts = content.split(";");
        for (String part : parts) {
            part = part.trim();
            if (!part.isEmpty()) {
                statements.add(part); // 不带分号
            }
        }
        return statements;
    }

    /**
     * ✅ 改进正则：支持跨行，使用 DOTALL 模式
     */
    private static SqlTemplate parseInsertSql(String sql) {
        // 使用 DOTALL 模式，让 . 匹配换行符
        Pattern pattern = Pattern.compile(
                "INSERT\\s+INTO\\s+(\\S+\\s*\\([^)]+\\))\\s+VALUES\\s*\\(([^)]*)\\)",
                Pattern.CASE_INSENSITIVE | Pattern.DOTALL
        );
        Matcher matcher = pattern.matcher(sql);

        if (!matcher.find()) {
            throw new IllegalArgumentException("不支持的 SQL 格式（必须是标准 INSERT）: " + sql);
        }

        String tableWithColumns = matcher.group(1);
        String valuesPlaceholder = matcher.group(2); // 用于计算参数数量

        // 计算参数数量（按逗号分割，但需处理字符串内的逗号 → 简化处理）
        int paramCount = valuesPlaceholder.isEmpty() ? 0 : valuesPlaceholder.split(",").length;

        // 构建参数化模板
        String placeholders = String.join(",", java.util.Collections.nCopies(paramCount, "?"));
        String template = "INSERT INTO " + tableWithColumns + " VALUES (" + placeholders + ")";

        return new SqlTemplate(template, paramCount);
    }

    /**
     * ✅ 改进参数提取：从完整 SQL 中提取 VALUES 部分
     */
    private static Object[] extractParams(String sql) {
        // 找到 VALUES 后的内容
        int valuesIndex = sql.toUpperCase().lastIndexOf("VALUES");
        if (valuesIndex == -1) {
            throw new IllegalArgumentException("未找到 VALUES: " + sql);
        }
        String valuesPart = sql.substring(valuesIndex + 6).trim(); // "VALUES" 长度为 6

        // 移除外层括号
        if (valuesPart.startsWith("(") && valuesPart.endsWith(")")) {
            valuesPart = valuesPart.substring(1, valuesPart.length() - 1).trim();
        }

        List<Object> params = new ArrayList<>();
        // 简单按逗号分割（不处理字符串内的逗号）
        String[] rawValues = valuesPart.split(",");

        for (String raw : rawValues) {
            raw = raw.trim();
            if (raw.equalsIgnoreCase("NULL")) {
                params.add(null);
            } else if (raw.startsWith("'") && raw.endsWith("'")) {
                params.add(raw.substring(1, raw.length() - 1));
            } else if (raw.matches("-?\\d+")) {
                params.add(Long.parseLong(raw));
            } else if (raw.matches("-?\\d*\\.\\d+")) {
                params.add(Double.parseDouble(raw));
            } else {
                // 尝试作为字符串处理（如包含逗号的字符串会出错，但简单场景够用）
                if (!raw.isEmpty()) {
                    params.add(raw);
                }
            }
        }

        return params.toArray();
    }

    private static class SqlTemplate {
        private final String sqlTemplate;
        private final int paramCount;

        public SqlTemplate(String sqlTemplate, int paramCount) {
            this.sqlTemplate = sqlTemplate;
            this.paramCount = paramCount;
        }

        public String getSqlTemplate() {
            return sqlTemplate;
        }

        public int getParamCount() {
            return paramCount;
        }
    }


//    // 通用方法
//    private static final int BATCH_SIZE = 50;
//
//    /**
//     * 批量执行 SQL 文件（分批次提交）
//     *
//     * @param conn        数据库连接（由调用方提供）
//     * @param sqlFilePath SQL 文件路径
//     * @throws IOException  文件读取异常
//     * @throws SQLException 数据库异常
//     */
//    public static void executeSqlFileInBatches(Connection conn, String sqlFilePath)
//            throws IOException, SQLException {
//        List<String> allSqls = readSqlFile(sqlFilePath);
//        System.out.println("共读取 " + allSqls.size() + " 条 SQL 语句");
//
//        conn.setAutoCommit(false);
//        int total = allSqls.size();
//        int batchCount = 0;
//
//        for (int i = 0; i < total; i += BATCH_SIZE) {
//            int end = Math.min(i + BATCH_SIZE, total);
//            List<String> batch = allSqls.subList(i, end);
//
//            executeBatch(conn, batch);
//            conn.commit();
//
//            batchCount++;
//            System.out.printf("✅ 已提交第 %d 批次（%d ~ %d / %d）\n",
//                    batchCount, i + 1, end, total);
//        }
//    }
//
//    /**
//     * 读取 SQL 文件，解析为语句列表
//     */
//    private static List<String> readSqlFile(String filePath) throws IOException {
//        List<String> statements = new ArrayList<>();
//        StringBuilder current = new StringBuilder();
//
//        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                line = line.trim();
//                if (line.startsWith("--") || line.startsWith("#") || line.isEmpty()) {
//                    continue;
//                }
//
//                current.append(line).append(" ");
//                if (line.endsWith(";")) {
//                    String sql = current.toString().trim();
//                    if (sql.endsWith(";")) {
//                        sql = sql.substring(0, sql.length() - 1).trim();
//                    }
//                    if (!sql.isEmpty()) {
//                        statements.add(sql);
//                    }
//                    current.setLength(0);
//                }
//            }
//
//            if (current.length() > 0) {
//                String sql = current.toString().trim();
//                if (!sql.isEmpty()) {
//                    statements.add(sql);
//                }
//            }
//        }
//        return statements;
//    }
//
//    private static void executeBatch(Connection conn, List<String> sqlBatch) throws SQLException {
//        try (Statement stmt = conn.createStatement()) {
//            for (String sql : sqlBatch) {
//                if (!sql.trim().isEmpty()) {
//                    stmt.execute(sql);
//                }
//            }
//        }
//    }




//    // MySQL 连接信息（请根据实际情况修改）
//    private static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/spwuat?useSSL=false&serverTimezone=UTC";
//    private static final String DB_USER = "mes_cf";
//    private static final String DB_PASSWORD = "123456";
//
//    /**
//     * 主方法：执行 SQL 文件
//     */
//    public static void main(String[] args) {
//        String sqlFilePath = "src/test/resources/students.sql"; // SQL 文件路径（相对于项目根目录或绝对路径）
//
//        try {
////            executeSqlFile(sqlFilePath);
//            executeSqlFileInBatches(sqlFilePath);
//            System.out.println("✅ SQL 文件执行成功！");
//        } catch (Exception e) {
//            System.err.println("❌ 执行失败: " + e.getMessage());
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * 读取 SQL 文件并执行所有语句
//     *
//     * @param sqlFilePath SQL 文件路径
//     * @throws IOException  文件读取异常
//     * @throws SQLException 数据库操作异常
//     */
//    public static void executeSqlFile(String sqlFilePath) throws IOException, SQLException {
//        // 1. 读取 SQL 文件内容
//        List<String> sqlStatements = readSqlFile(sqlFilePath);
//
//        // 2. 连接数据库并执行
//        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
//             Statement stmt = conn.createStatement()) {
//
//            // 关闭自动提交，使用事务（可选，提升性能）
//            conn.setAutoCommit(false);
//
//            for (String sql : sqlStatements) {
//                if (sql.trim().isEmpty()) continue; // 跳过空行
//                System.out.println("执行 SQL: " + sql);
//                stmt.execute(sql); // execute() 支持 INSERT/UPDATE/DELETE/DDL
//            }
//
//            conn.commit(); // 提交事务
//            System.out.println("共执行 " + sqlStatements.size() + " 条 SQL 语句");
//        }
//    }
//
//    /**
//     * 读取 SQL 文件，按分号分割成多条语句
//     *
//     * @param filePath 文件路径
//     * @return SQL 语句列表
//     * @throws IOException 文件读取异常
//     */
//    private static List<String> readSqlFile(String filePath) throws IOException {
//        List<String> statements = new ArrayList<>();
//        StringBuilder currentStatement = new StringBuilder();
//
//        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                // 移除注释（-- 开头的行）
//                if (line.trim().startsWith("--") || line.trim().startsWith("#")) {
//                    continue;
//                }
//
//                // 累加当前行
//                currentStatement.append(line).append(" ");
//
//                // 如果行以分号结尾，认为是一条完整语句
//                if (line.trim().endsWith(";")) {
//                    String sql = currentStatement.toString().trim();
//                    // 移除末尾分号
//                    if (sql.endsWith(";")) {
//                        sql = sql.substring(0, sql.length() - 1).trim();
//                    }
//                    if (!sql.isEmpty()) {
//                        statements.add(sql);
//                    }
//                    currentStatement.setLength(0); // 清空
//                }
//            }
//
//            // 处理文件末尾没有分号的情况（不推荐，但兼容）
//            if (currentStatement.length() > 0) {
//                String sql = currentStatement.toString().trim();
//                if (!sql.isEmpty()) {
//                    statements.add(sql);
//                }
//            }
//        }
//
//        return statements;
//    }
//
//
//    /**
//     * 分批次执行 SQL 文件
//     */
//    private static final int BATCH_SIZE = 50;
//
//    public static void executeSqlFileInBatches(String sqlFilePath) throws IOException, SQLException {
//        List<String> allSqls = readSqlFile(sqlFilePath);
//        System.out.println("共读取 " + allSqls.size() + " 条 SQL 语句");
//
//        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
//            // 启用批量重写（MySQL 优化）
//            conn.setAutoCommit(false);
//
//            int total = allSqls.size();
//            int batchCount = 0;
//
//            for (int i = 0; i < total; i += BATCH_SIZE) {
//                int end = Math.min(i + BATCH_SIZE, total);
//                List<String> batch = allSqls.subList(i, end);
//
//                executeBatch(conn, batch);
//                conn.commit(); // 提交当前批次
//
//                batchCount++;
//                System.out.printf("✅ 已提交第 %d 批次（%d ~ %d / %d）\n",
//                        batchCount, i + 1, end, total);
//            }
//        }
//    }
//
//    /**
//     * 执行一个批次的 SQL 语句
//     */
//    private static void executeBatch(Connection conn, List<String> sqlBatch) throws SQLException {
//        try (Statement stmt = conn.createStatement()) {
//            for (String sql : sqlBatch) {
//                if (!sql.trim().isEmpty()) {
//                    stmt.execute(sql);
//                }
//            }
//        }
//    }

}
